Completed
Push — js-scrutinizing ( 5b02b9...3d2f6f )
by Maxence
02:12
created

$(document).ready   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 13

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
c 1
b 0
f 0
nc 1
nop 1
dl 0
loc 13
rs 9.4285
1
/*
2
 * Circles - Bring cloud-users closer together.
3
 *
4
 * This file is licensed under the Affero General Public License version 3 or
5
 * later. See the COPYING file.
6
 *
7
 * @author Maxence Lange <[email protected]>
8
 * @copyright 2017
9
 * @license GNU AGPL version 3 or any later version
10
 *
11
 * This program is free software: you can redistribute it and/or modify
12
 * it under the terms of the GNU Affero General Public License as
13
 * published by the Free Software Foundation, either version 3 of the
14
 * License, or (at your option) any later version.
15
 *
16
 * This program is distributed in the hope that it will be useful,
17
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19
 * GNU Affero General Public License for more details.
20
 *
21
 * You should have received a copy of the GNU Affero General Public License
22
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
23
 *
24
 */
25
26
/** global: OC */
27
/** global: OCA */
28
/** global: Notyf */
29
30
$(document).ready(function () {
31
32
	/**
33
	 * @constructs Navigation
34
	 */
35
	var Navigation = function () {
36
		this.initialize();
37
	};
38
39
	Navigation.prototype = {
40
41
		initialize: function () {
42
			var self = this;
43
			var api = OCA.Circles.api;
44
45
			var currCirclesType = '';
46
			var currentCircle = 0;
47
			var currentCircleLevel = 0;
48
			var lastSearchCircle = '';
49
			var lastSearchUser = '';
50
51
			var divNewTypeDefinition = $('#circles_new_type_definition');
52
			var divNewType = $('#circles_new_type');
53
			var divNewSubmit = $('#circles_new_submit');
54
			var divNewName = $('#circles_new_name');
55
			var divNavigation = $('#app-navigation.circles');
56
			var divCirclesList = $('#circles_list');
57
			var divEmptyContent = $('#emptycontent');
58
			var divMainUI = $('#mainui');
59
			var divMainUIMembers = $('#memberslist_table');
60
			var divMembersSearchResult = $('#members_search_result');
61
62
			var divJoinCircleAccept = $('#joincircle_acceptinvit');
63
			var divJoinCircleReject = $('#joincircle_rejectinvit');
64
			var divJoinCircleRequest = $('#joincircle_request');
65
			var divJoinCircleInvite = $('#joincircle_invit');
66
			var divJoinCircle = $('#joincircle');
67
			var divLeaveCircle = $('#leavecircle');
68
69
			/**
70
			 *
71
			 * @constructor
72
			 */
73
			this.UIReset = function () {
74
				divNewTypeDefinition.children('div').fadeOut(0);
75
				$('#circles_new_type_' + divNewType.children('option:selected').val()).fadeIn(0);
76
77
				divNewType.hide();
78
				divNewSubmit.hide();
79
				divNewTypeDefinition.hide();
80
81
				$('.icon-circles').css('background-image',
82
					'url(' + OC.imagePath('circles', 'colored') + ')');
83
84
				divMembersSearchResult.hide();
85
			};
86
87
			/**
88
			 *
89
			 */
90
			this.initTweaks = function () {
91
				$.fn.emptyTable = function () {
92
					this.children('tr').each(function () {
93
						if ($(this).attr('class') != 'header') {
94
							$(this).remove();
95
						}
96
					});
97
				};
98
99
				// $.fn.hideEntry = function () {
100
				// 	this.children('tr').each(function () {
101
				// 		if ($(this).attr('class') != 'header') {
102
				// 			$(this).remove();
103
				// 		}
104
				// 	});
105
				// }
106
			};
107
108
109
			/**
110
			 *
111
			 */
112
			this.initAnimationNewCircle = function () {
113
114
				divNewName.on('keyup', function () {
115
					self.onEventNewCircleName();
116
				});
117
118
				divNewType.on('change', function () {
119
					self.onEventNewCircleType();
120
				});
121
122
				divNewSubmit.on('click', function () {
123
					api.createCircle(divNewType.val(), divNewName.val(),
124
						self.createCircleResult);
125
				});
126
127
			};
128
129
130
			/**
131
			 *
132
			 */
133
			this.onEventNewCircle = function () {
134
135
				currentCircle = 0;
136
				currentCircleLevel = 0;
137
138
				divNavigation.hide('slide', 800);
139
				divCirclesList.children('div').removeClass('selected');
140
				divEmptyContent.show(800);
141
				divMainUI.fadeOut(800);
142
			};
143
144
			/**
145
			 *
146
			 */
147
			this.onEventNewCircleName = function () {
148
				this.onEventNewCircle();
149
				this.displayOptionsNewCircle((divNewName.val() !== ''));
150
			};
151
152
			/**
153
			 *
154
			 */
155
			this.onEventNewCircleType = function () {
156
				this.onEventNewCircle();
157
				divNewTypeDefinition.children('div').fadeOut(300);
158
				$('#circles_new_type_' + divNewType.children('option:selected').val()).fadeIn(
159
					300);
160
			};
161
162
			/**
163
			 *
164
			 * @param display
165
			 */
166
			this.displayOptionsNewCircle = function (display) {
167
				if (display) {
168
					divNewType.fadeIn(300);
169
					divNewSubmit.fadeIn(500);
170
					divNewTypeDefinition.fadeIn(700);
171
				}
172
				else {
173
					divNewType.fadeOut(700);
174
					divNewSubmit.fadeOut(500);
175
					divNewTypeDefinition.fadeOut(300);
176
				}
177
			};
178
179
180
			/**
181
			 *
182
			 */
183
			this.initExperienceCirclesList = function () {
184
185
				divCirclesList.children('div').on('click', function () {
186
					self.displayCirclesList($(this).attr('circle-type'));
187
				});
188
189
				$('#circles_search').on('input propertychange paste focus', function () {
190
					if (lastSearchCircle == $(this).val().trim()) {
191
						return;
192
					}
193
194
					lastSearchCircle = $(this).val().trim();
195
					api.searchCircles(currCirclesType, $(this).val().trim(),
196
						self.listCirclesResult);
197
				});
198
199
			};
200
201
202
			/**
203
			 *
204
			 */
205
			this.initExperienceManagerMembers = function () {
206
				$('#joincircle').on('click', function () {
207
					api.joinCircle(currentCircle, self.joinCircleResult);
208
				});
209
210
				$('#leavecircle').on('click', function () {
211
					api.leaveCircle(currentCircle, self.leaveCircleResult);
212
				});
213
214
				$('#joincircle_acceptinvit').on('click', function () {
215
					api.joinCircle(currentCircle, self.joinCircleResult);
216
				});
217
218
				$('#joincircle_rejectinvit').on('click', function () {
219
					api.leaveCircle(currentCircle, self.leaveCircleResult);
220
				});
221
222
				$('#addmember').on('input propertychange paste focus', function () {
223
					self.searchMembersRequest($(this).val().trim());
224
				}).blur(function () {
225
					divMembersSearchResult.fadeOut(400);
226
				});
227
			};
228
229
230
			/**
231
			 *
232
			 * @param result
233
			 */
234
			this.createCircleResult = function (result) {
235
				var str = self.getStringTypeFromType(result.type);
236
237
				if (result.status == 1) {
238
					OCA.notification.onSuccess(str + " '" + result.name + "' created");
239
					self.displayCirclesList(result.circle.type);
240
					self.selectCircle(result.circle.id);
241
					return;
242
				}
243
244
				OCA.notification.onFail(
245
					str + " '" + result.name + "' NOT created: " +
246
					((result.error) ? result.error : 'no error message'));
247
			};
248
249
250
			/**
251
			 *
252
			 * @param type
253
			 * @returns {*}
254
			 */
255
			this.getStringTypeFromType = function (type) {
256
				switch (type) {
0 ignored issues
show
Coding Style introduced by
As per coding-style, switch statements should have a default case.
Loading history...
257
					case '1':
258
						return 'Personal circle';
259
					case '2':
260
						return 'Hidden circle';
261
					case '4':
262
						return 'Private circle';
263
					case '8':
264
						return 'Public circle';
265
				}
266
267
				return 'Circle';
268
			};
269
270
271
			/**
272
			 *
273
			 * @param type
274
			 */
275
			this.displayCirclesList = function (type) {
276
277
				currCirclesType = type;
278
				lastSearchCircle = '';
279
				lastSearchUser = '';
280
281
				currentCircle = 0;
282
				currentCircleLevel = 0;
283
284
				divNavigation.show('slide', 800);
285
				divEmptyContent.show(800);
286
				divMainUI.fadeOut(800);
287
288
				$('#circles_search').val('');
289
				$('#addmember').val('');
290
291
				this.UIresetCirclesList(type);
292
				api.listCircles(type, self.listCirclesResult);
293
			};
294
295
296
			/**
297
			 *
298
			 * @constructor
299
			 */
300
			this.UIresetCirclesList = function (type) {
301
302
				divCirclesList.children('div').removeClass('selected');
303
				divCirclesList.children().each(function () {
304
					if ($(this).attr('circle-type') == type.toLowerCase()) {
305
						$(this).addClass('selected');
306
					}
307
				});
308
309
				divNavigation.addClass('selected');
310
				divNavigation.children().each(function () {
311
					if ($(this).attr('id') != 'circles_search') {
312
						$(this).remove();
313
					}
314
				});
315
			};
316
317
318
			/**
319
			 *
320
			 * @param result
321
			 */
322
			this.listCirclesResult = function (result) {
323
324
				if (result.status < 1) {
325
					OCA.notification.onFail(
326
						'Issue while retreiving the list of the Circles: ' +
327
						((result.error) ? result.error : 'no error message'));
328
					return;
329
				}
330
331
				var data = result.data;
332
				for (var i = 0; i < data.length; i++) {
333
					var tmpl = self.generateTmplCircle(data[i]);
334
					divNavigation.append(
335
						'<div class="circle" circle-id="' + data[i].id + '">' + tmpl + '</div>');
336
				}
337
338
				divNavigation.children('.circle').on('click', function () {
339
					self.selectCircle($(this).attr('circle-id'));
340
				});
341
			};
342
343
344
			/**
345
			 *
346
			 * @returns {*|jQuery}
347
			 * @param entry
348
			 */
349
			this.generateTmplCircle = function (entry) {
350
				var tmpl = $('#tmpl_circle').html();
351
352
				tmpl = tmpl.replace(/%title%/, entry.name);
353
				tmpl = tmpl.replace(/%type%/, entry.type);
354
				tmpl = tmpl.replace(/%owner%/, entry.owner.user_id);
355
				tmpl = tmpl.replace(/%status%/, entry.user.status);
356
				tmpl = tmpl.replace(/%level_string%/, entry.user.level_string);
357
				tmpl = tmpl.replace(/%count%/, entry.count);
358
				tmpl = tmpl.replace(/%creation%/, entry.creation);
359
360
				return tmpl;
361
			};
362
363
364
			/**
365
			 *
366
			 * @param circle_id
367
			 */
368
			this.selectCircle = function (circle_id) {
369
				lastSearchUser = '';
370
				$('#addmember').val('');
371
372
				api.detailsCircle(circle_id, this.selectCircleResult);
373
			};
374
375
376
			this.selectCircleResult = function (result) {
377
378
				divMainUIMembers.emptyTable();
379
380
				if (result.status < 1) {
381
					OCA.notification.onFail(
382
						'Issue while retreiving the details of a circle: ' +
383
						((result.error) ? result.error : 'no error message'));
384
					return;
385
				}
386
387
				divNavigation.children('.circle').each(function () {
388
					if ($(this).attr('circle-id') == result.circle_id) {
389
						$(this).addClass('selected');
390
					} else {
391
						$(this).removeClass('selected');
392
					}
393
				});
394
				divEmptyContent.hide(800);
395
				divMainUI.fadeIn(800);
396
				currentCircle = result.circle_id;
397
				currentCircleLevel = result.details.user.level;
398
399
				if (result.details.user.level < 6) {
400
					$('#addmember').hide();
401
				} else {
402
					$('#addmember').show();
403
				}
404
405
406
				divJoinCircleAccept.hide();
407
				divJoinCircleReject.hide();
408
				divJoinCircleRequest.hide();
409
				divJoinCircleInvite.hide();
410
411
				if (result.details.user.level == 9) {
412
					divJoinCircle.hide();
413
					divLeaveCircle.hide();
414
				}
415
				else if (result.details.user.level >= 1) {
416
					divJoinCircle.hide();
417
					divLeaveCircle.show();
418
				} else {
419
					if (result.details.user.status == 'Invited') {
420
						divJoinCircleInvite.show();
421
						divJoinCircleAccept.show();
422
						divJoinCircleReject.show();
423
						divJoinCircle.hide();
424
						divLeaveCircle.hide();
425
					}
426
					else if (result.details.user.status == 'Requesting') {
427
						divJoinCircleRequest.show();
428
						divJoinCircle.hide();
429
						divLeaveCircle.show();
430
					}
431
					else {
432
						divJoinCircle.show();
433
						divLeaveCircle.hide();
434
					}
435
				}
436
437
				self.displayMembers(result.details.members);
438
			};
439
440
441
			/**
442
			 *
443
			 * @param search
444
			 */
445
			this.searchMembersRequest = function (search) {
446
447
				if (lastSearchUser == search) {
448
					return;
449
				}
450
451
				lastSearchUser = search;
452
453
				$.get(OC.linkToOCS('apps/files_sharing/api/v1', 1) + 'sharees',
454
					{
455
						format: 'json',
456
						search: search,
457
						perPage: 200,
458
						itemType: 'principals'
459
					}, self.searchMembersResult);
460
			};
461
462
463
			this.searchMembersResult = function (response) {
464
465
				if (response === null ||
466
					(response.ocs.data.users === 0 && response.ocs.data.exact.users === 0)) {
467
					divMembersSearchResult.fadeOut(300);
468
				}
469
				else {
470
					var currSearch = $('#addmember').val().trim();
471
					divMembersSearchResult.children().remove();
472
473
					$.each(response.ocs.data.exact.users, function (index, value) {
474
						divMembersSearchResult.append(
475
							'<div class="members_search exact" searchresult="' +
476
							value.value.shareWith + '">' + value.label + '   (' +
477
							value.value.shareWith + ')</div>');
478
					});
479
480
					$.each(response.ocs.data.users, function (index, value) {
481
						var line = value.label + '   (' + value.value.shareWith + ')';
482
						if (currSearch.length > 0) {
483
							line =
484
								line.replace(new RegExp('(' + currSearch + ')', 'gi'), '<b>$1</b>');
485
						}
486
487
						divMembersSearchResult.append(
488
							'<div class="members_search" searchresult="' + value.value.shareWith +
489
							'">' + line + '</div>');
490
					});
491
492
					divMembersSearchResult.children().first().css('border-top-width', '0px');
493
494
					$('.members_search').on('click', function () {
495
						api.addMember(currentCircle, $(this).attr('searchresult'),
496
							self.addMemberResult);
497
					});
498
					divMembersSearchResult.fadeIn(300);
499
				}
500
501
			};
502
503
504
			this.addMemberResult = function (result) {
505
506
				if (result.status == 1) {
507
					OCA.notification.onSuccess(
508
						"Member '" + result.name + "' successfully added to the circle");
509
510
					return self.displayMembers(result.members);
511
				}
512
				OCA.notification.onFail(
513
					"Member '" + result.name + "' NOT added to the circle: " +
514
					((result.error) ? result.error : 'no error message'));
0 ignored issues
show
Best Practice introduced by
There is no return statement in this branch, but you do return something in other branches. Did you maybe miss it? If you do not want to return anything, consider adding return undefined; explicitly.
Loading history...
515
			};
516
517
518
			this.displayMembers = function (members) {
519
520
				divMainUIMembers.emptyTable();
521
522
				if (members === null) {
523
					divMainUIMembers.hide(200);
524
					return;
525
				}
526
527
				divMainUIMembers.show(200);
528
				for (var i = 0; i < members.length; i++) {
529
530
					var tmpl = $('#tmpl_member').html();
531
532
					tmpl = tmpl.replace(/%username%/g, members[i].user_id);
533
					tmpl = tmpl.replace(/%level%/g, members[i].level);
534
					tmpl = tmpl.replace(/%levelstring%/g, members[i].level_string);
535
					tmpl = tmpl.replace(/%status%/, members[i].status);
536
					tmpl = tmpl.replace(/%joined%/, members[i].joined);
537
					tmpl = tmpl.replace(/%note%/,
538
						((members[i].note) ? members[i].note : ''));
539
540
					divMainUIMembers.append(tmpl);
541
				}
542
543
				divMainUIMembers.children().each(function () {
544
					if ($(this).attr('member-level') == '9' || currentCircleLevel < 6) {
545
						$(this).children('.delete').hide(0);
546
					}
547
				});
548
549
				divMainUIMembers.children('.delete').on('click', function () {
550
					var member = $(this).parent().attr('member-id');
551
					api.removeMember(currentCircle, member, self.removeMemberResult);
552
				});
553
			};
554
555
556
			this.removeMemberResult = function (result) {
557
				if (result.status == 1) {
558
559
					divMainUIMembers.children().each(function () {
560
						if ($(this).attr('member-id') == result.name) {
561
							$(this).hide(300);
562
						}
563
					});
564
565
					OCA.notification.onSuccess(
566
						"Member '" + result.name + "' successfully removed from the circle");
567
					return;
568
				}
569
570
				OCA.notification.onFail(
571
					"Member '" + result.name + "' NOT removed from the circle: " +
572
					((result.error) ? result.error : 'no error message'));
573
574
			};
575
576
577
			this.joinCircleResult = function (result) {
578
				if (result.status == 1) {
579
580
					divMainUIMembers.children().each(function () {
581
						if ($(this).attr('member-id') == result.name) {
582
							$(this).hide(300);
583
						}
584
					});
585
586
					if (result.member.level == 1) {
587
						OCA.notification.onSuccess(
588
							"You have successfully joined this circle");
589
					} else {
590
						OCA.notification.onSuccess(
591
							"You have requested an invitation to join this circle");
592
					}
593
					return self.selectCircle(result.circle_id);
594
				}
595
596
				OCA.notification.onFail(
597
					"Cannot join this circle: " +
598
					((result.error) ? result.error : 'no error message'));
0 ignored issues
show
Best Practice introduced by
There is no return statement in this branch, but you do return something in other branches. Did you maybe miss it? If you do not want to return anything, consider adding return undefined; explicitly.
Loading history...
599
600
			};
601
602
			this.leaveCircleResult = function (result) {
603
				if (result.status == 1) {
604
605
					divMainUIMembers.children().each(function () {
606
						if ($(this).attr('member-id') == result.name) {
607
							$(this).hide(300);
608
						}
609
					});
610
611
					OCA.notification.onSuccess(
612
						"You have successfully left this circle");
613
614
					self.selectCircle(result.circle_id);
615
				}
616
				else {
617
					OCA.notification.onFail(
618
						"Cannot leave this circle: " +
619
						((result.error) ? result.error : 'no error message'));
620
				}
621
			};
622
623
624
			/**
625
			 * Inits
626
			 */
627
			this.initTweaks();
628
			this.UIReset();
629
			this.initAnimationNewCircle();
630
			this.initExperienceCirclesList();
631
			this.initExperienceManagerMembers();
632
633
		}
634
	};
635
636
637
	/**
638
	 * @constructs Notification
639
	 */
640
	var Notification = function () {
641
		this.initialize();
642
	};
643
644
	Notification.prototype = {
645
646
		initialize: function () {
647
648
			//noinspection SpellCheckingInspection
649
			var notyf = new Notyf({
650
				delay: 5000
651
			});
652
653
			this.onSuccess = function (text) {
654
				notyf.confirm(text);
655
			};
656
657
			this.onFail = function (text) {
658
				notyf.alert(text);
659
			};
660
661
		}
662
663
	};
664
665
	OCA.Circles.Navigation = Navigation;
666
	OCA.Circles.navigation = new Navigation();
667
668
	OCA.Notification = Notification;
669
	OCA.notification = new Notification();
670
671
});
672
673